﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

using Alicanto.Helpers;
using Alicanto.Lexing;

namespace Alicanto.Compilation.Code.Operators.Numeric
{
    internal class OpSubtract : ICodeGenerator
    {
        public Expression Code { get; private set; }

        public IEnumerable<ParseInstruction> Generate(TokenSequence tokens, Scope scope)
        {
            GetEvaluation evaluation = new GetEvaluation();
            yield return evaluation;

            ParseExpressionRemainder remainder = new ParseExpressionRemainder();
            yield return remainder;

            Expression x = evaluation.Expression;
            Expression y = remainder.Remainder;

            if (x.Type == typeof(void))
                x = Expression.Constant(0);

            // Dynamic
            if (x.Type == typeof(object) || y.Type == typeof(object))
            {
                this.Code = Expression.Dynamic(
                    Binding.CreateBinaryBinder(ExpressionType.Subtract),
                    typeof(object),
                    x,
                    y
                );
            }
            // Number + Number
            else if (Typing.IsNumber(x.Type) && Typing.IsNumber(y.Type))
            {
                Conversion.EqualizeNumbers(ref x, ref y);
                this.Code = Expression.Subtract(
                    x,
                    y
                );
            }
        }
    }
}
